package com.seari.service;


import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seari.bean.AllFullLoadBean;
import com.seari.bean.CellBean;
import com.seari.bean.IorBean;
import com.seari.bean.ResultTrain;
import com.seari.bean.WindowInfo;
import com.seari.controller.ATSWebsocketController;
import com.seari.mapper.TrainMapper;
import com.seari.pojo.ATSMessageBean;

@Service
public class TrainServiceImpl implements TrainService 
{
	protected static Logger logger = LoggerFactory.getLogger(TrainServiceImpl.class);
	public static Map<String, HashMap<String, WindowInfo>> windowInfoMap = new HashMap<>(); //静态配置信息
	public static volatile Map<String, ConcurrentHashMap<String, ResultTrain>> trainMap = new ConcurrentHashMap<>(); //列车动态信息，多线程访问
	public static Map<String, HashMap<String, IorBean>> iorUrlRefMap = new HashMap<>(); 
	public final static ObjectMapper MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	public static Map<String, HashMap<String, CellBean>> cellMap = new HashMap<>();
	@Autowired
	private TrainMapper trainMapper;
	@Autowired
	private AppCacheService appCacheService;
	
	@Override
	public void initTrainData()
	{
		//将列车MAP添加至appcache
		appCacheService.refreshCache("trainMap", trainMap);
		//初始化车次窗信息
		List<WindowInfo> windowInfos = trainMapper.getAllWindowInfo();
		if(windowInfos != null && windowInfos.size() > 0)
		{
			for(int i=0 ; i < windowInfos.size();i++)
			{
				WindowInfo windowInfo = windowInfos.get(i);
				String lineId = windowInfo.getLineId();
				if(!windowInfoMap.containsKey(lineId))
				{
					//若不存在，则新建hashMap实例
					windowInfoMap.put(lineId, new HashMap<String, WindowInfo>());
				}else {
					//若存在，则向hashMap中添加数据
					HashMap<String, WindowInfo> targetMap = windowInfoMap.get(lineId);
					targetMap.put(windowInfo.getWindow(), windowInfo);
				}
			}
		}
		
		//初始化IOR信息
		List<IorBean> iorBeans = trainMapper.getIorReference();
		for (IorBean iorBean : iorBeans)
		{
			if(!iorUrlRefMap.containsKey(iorBean.getLineId()))
			{
				HashMap<String, IorBean> resultMap = new HashMap<>();
				resultMap.put(iorBean.getAtsTrain(), iorBean);
				iorUrlRefMap.put(iorBean.getLineId(), resultMap);
			}else {
				iorUrlRefMap.get(iorBean.getLineId()).put(iorBean.getAtsTrain(), iorBean);
			}
		}
		
		//初始化区间信息，供车辆满载率使用
		List<CellBean> cellBeans = trainMapper.getAllCellInfo();
		for (CellBean cellBean : cellBeans)
		{
			if(!cellMap.containsKey(cellBean.getLineId()))
			{
				HashMap<String, CellBean> resultMap = new HashMap<>();
				resultMap.put(cellBean.getCellId(), cellBean);
				cellMap.put(cellBean.getLineId(), resultMap);
			}else {
				cellMap.get(cellBean.getLineId()).put(cellBean.getCellId(), cellBean);
			}
		}
	}
	
	@Override
	public void removeTrainByTrainGroupIds(List<String> groupIds,String lineId)
	{
		ConcurrentHashMap<String, ResultTrain> resultMap = trainMap.get(lineId);
		if(resultMap != null)
		{
			for (String gid : groupIds)
			{
				ResultTrain resultTrain = resultMap.get(gid);
				if(null != resultTrain)
				{
					ATSMessageBean atsMessageBean = new ATSMessageBean();
					atsMessageBean.setType("remove");
					atsMessageBean.setData(resultTrain);
					try
					{
						//删除车辆消息发送至websocket
						ATSWebsocketController.broadCastInfo(MAPPER.writeValueAsString(atsMessageBean));
						//删除缓存MAP中的车辆数据
						resultMap.remove(gid);
					} catch (JsonProcessingException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}

	@Override
	public void removeTrainByTrainIndexes(List<String> indexes, String lineId)
	{
		ConcurrentHashMap<String, ResultTrain> resultMap = trainMap.get(lineId);
		if(resultMap != null)
		{
			for(String index : indexes) {
				Iterator<Entry<String, ResultTrain>> iterator = resultMap.entrySet().iterator();
				while (iterator.hasNext())
				{
					ResultTrain resultTrain = iterator.next().getValue();
					if(index.equals(resultTrain.getTrainIndex()))
					{
						ATSMessageBean atsMessageBean = new ATSMessageBean();
						atsMessageBean.setType("remove");
						atsMessageBean.setData(resultTrain);
						try
						{
							//删除车辆消息发送至websocket
							ATSWebsocketController.broadCastInfo(MAPPER.writeValueAsString(atsMessageBean));
							//删除缓存MAP中的车辆数据
							iterator.remove();
							break;
						} catch (JsonProcessingException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}
	}

	@Override
	public void removeTrainByTrainGroupId(String groupId, String lineId)
	{
		ConcurrentHashMap<String, ResultTrain> resultMap = trainMap.get(lineId);
		if(resultMap != null)
		{
			ResultTrain resultTrain = resultMap.get(groupId);
			if(null != resultTrain)
			{
				ATSMessageBean atsMessageBean = new ATSMessageBean();
				atsMessageBean.setType("remove");
				atsMessageBean.setData(resultTrain);
				try
				{
					//删除车辆消息发送至websocket
					ATSWebsocketController.broadCastInfo(MAPPER.writeValueAsString(atsMessageBean));
					//删除缓存MAP中的车辆数据
					resultMap.remove(groupId);
				} catch (JsonProcessingException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public void removeTrainByTrainIndex(String index, String lineId)
	{
		ConcurrentHashMap<String, ResultTrain> resultMap = trainMap.get(lineId);
		if(resultMap != null)
		{
			Iterator<Entry<String, ResultTrain>> iterator = resultMap.entrySet().iterator();
			while (iterator.hasNext())
			{
				ResultTrain resultTrain = iterator.next().getValue();
				if(index.equals(resultTrain.getTrainIndex()))
				{
					ATSMessageBean atsMessageBean = new ATSMessageBean();
					atsMessageBean.setType("remove");
					atsMessageBean.setData(resultTrain);
					try
					{
						//删除车辆消息发送至websocket
						ATSWebsocketController.broadCastInfo(MAPPER.writeValueAsString(atsMessageBean));
						//删除缓存MAP中的车辆数据
						iterator.remove();
						break;
					} catch (JsonProcessingException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}

	@Override
	public List<IorBean> getIorReference()
	{
		// TODO Auto-generated method stub
		return trainMapper.getIorReference();
	}

	@Override
	public Map<String, Map<String, Integer>> convertFullLoadDataToTrainInfo(List<AllFullLoadBean> data)
	{
		Map<String, Map<String, Integer>> resultMap = new HashMap<>();
		for (AllFullLoadBean allFullLoadBean : data)
		{
			String cellId = allFullLoadBean.getFstrCellsectid();
			String lineId = "";
			lineId = cellId.replace("CELL", "");
			if(lineId.length() < 4)
			{
				//小于3位时在前方补0
				lineId = "0" + lineId;
			}
			lineId = lineId.substring(0,2);
			Map<String, Integer> cellAndPlatformLoadMap = null;
			if(!resultMap.containsKey(lineId))
			{
				cellAndPlatformLoadMap = new HashMap<>();
			}else {
				cellAndPlatformLoadMap = resultMap.get(lineId);
			}
			//添加区间满载率
			cellAndPlatformLoadMap.put(cellId, allFullLoadBean.getLevel());
			//为区间的父子站台添加满载率
			try
			{
				if(cellMap.get(lineId).containsKey(cellId))
				{
					CellBean cellBean = cellMap.get(lineId).get(cellId);
					cellAndPlatformLoadMap.put(cellBean.getParentPlatform(), allFullLoadBean.getLevel());
					//终点站时，子站台使用对应区间的满载率
					if(cellBean.getTopoType().equals("终点"))
					{
						cellAndPlatformLoadMap.put(cellBean.getChildPlatform(), allFullLoadBean.getLevel());
					}
				}else {
					logger.warn("cell is not in the cellMap:{}",cellId);
				}
				resultMap.put(lineId, cellAndPlatformLoadMap);
			} catch (Exception e)
			{
				// TODO: handle exception
				logger.warn("exception caught:{},{}",lineId,cellId);
			}
			
		}
		return resultMap;
	}

	@Override
	public List<CellBean> getAllCellInfo()
	{
		// TODO Auto-generated method stub
		return trainMapper.getAllCellInfo();
	}

}
